package com.cup.wx.micro.service.impl;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.cup.common.encryption.AESUtils;
import com.cup.wx.config.WebChatConfig.WXAccountProperties;
import com.cup.wx.config.WebChatConfig.WXUrlProperties;
import com.cup.wx.micro.bean.AppletSession;
import com.cup.wx.micro.bean.WxAccessToken;
import com.cup.wx.micro.bean.WxUserInfo;
import com.cup.wx.micro.service.RedisService;
import com.cup.wx.micro.service.WXBaseService;
import com.cup.wx.micro.util.WebchatUtil;
/**
 * 微信基础 信息处理
 * @author alan.zhao
 */
@Service
@EnableConfigurationProperties({WXAccountProperties.class,WXUrlProperties.class})
public class WXBaseServiceImpl implements WXBaseService {
	
	@Autowired
	private WXAccountProperties wxaccount;
	
	@Autowired
	private WXUrlProperties wxurl;
	
	@Autowired
	private RestTemplate testTemplate;
	
	@Autowired
	private RedisService redisService;
	
	private Logger logger = LoggerFactory.getLogger(WXBaseServiceImpl.class);
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public void getRemoteAccessToken() {
		
		String tokenUrl = wxurl.getDomain() + String.format(wxurl.getAccesstoken(), wxaccount.getAppid(), 
				wxaccount.getAppsecret());
		
		logger.info("get weixin acesstoken");
		
		ResponseEntity<Map> tokenRS = testTemplate.getForEntity(tokenUrl, Map.class);
		
		Map<String, Object> result = tokenRS.getBody();
		
		for(String key : result.keySet()) {
			logger.info("key:{}, value:{}", key, result.get(key));
		}
		
		WxAccessToken token = new WxAccessToken();
		token.setAccessToken(result.get("access_token").toString());
		token.setExpiresIn(Integer.valueOf(result.get("expires_in").toString()));
		
		redisService.set("acesstoken", JSON.toJSON(token).toString());
    }
	
	@Override
	public WxAccessToken getRedisAcessToken() {
		
		if(redisService.exists("acesstoken")) {
			String josnStr = (String) redisService.get("acesstoken");
			WxAccessToken token = JSON.parseObject(josnStr, WxAccessToken.class);
			return token;
		}
		
		return null;
	}
	
	/**
	 * 微信公众号网页授权
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Map<String, Object> getAuthorizationAccessToken(String code) throws Exception {
		
        String requestUrl = wxurl.getDomain() + String.format(wxurl.getCodetoken(), wxaccount.getAppid(), 
				wxaccount.getAppsecret(), code); 
        
        logger.info("get weixin authorization access token");
        
        ResponseEntity<Map> tokenRS = testTemplate.getForEntity(requestUrl, Map.class);
        
        Map<String, Object> result = tokenRS.getBody();
        
        if(result.get("errcode") != null) {
        	 throw new Exception(result.get("errcode").toString());
        }
        
        // openid, access_token, scope
        return result; 
	}  
	
	/**
	 * 微信公众号获取用户信息
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public WxUserInfo getWxUserInfo(String accesstoken, String openid) {
		
		String requestUrl = wxurl.getDomain() + String.format(wxurl.getUserinfo(), accesstoken, openid); 
		
		logger.info("get weixin user info");
		
		ResponseEntity<Map> rs = testTemplate.getForEntity(requestUrl, Map.class);
		
		Map<String, String> result = rs.getBody();
		
		WxUserInfo userinfo = new WxUserInfo();
		userinfo.setOpenid(openid);
		userinfo.setNickname(result.get("nickname"));
		userinfo.setSex(result.get("sex"));
		userinfo.setProvince(result.get("province"));
		userinfo.setCity(result.get("city"));
		userinfo.setCountry(result.get("country"));
		userinfo.setHeadimgurl(result.get("headimgurl"));
		if(result.get("unionid") != null)
			userinfo.setUnionid(result.get("unionid"));
        
        return userinfo;
	}
	
	/**
	 * 小程序登录
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public AppletSession appletLogin(String appid, String secret, String code)  throws Exception {
		
		String requestUrl =  wxurl.getDomain() + String.format(wxurl.getJscode2session(), appid, secret, code);
		
		logger.info("get weixin applet login for sessionkey and openid");
        
        ResponseEntity<Map> tokenRS = testTemplate.getForEntity(requestUrl, Map.class);
        
        Map<String, String> result = tokenRS.getBody();
        
        if(result.get("errcode") != null) {
        	 throw new Exception(result.get("errcode"));
        }
        
        AppletSession session = new AppletSession();
        session.setOpenid(result.get("openid"));
        session.setSessionKey(result.get("session_key"));
        session.setUinionid(result.get("uinionid"));
        session.setSessionKey(AESUtils.encryptToString(result.get("openid")+"@"+result.get("session_key")+"@"+result.get("uinionid"), wxaccount.getAeskey()));
        
		return session;
	}
	
	/**
	 * 小程序解密用户信息
	 */
	@Override
	public Map<String, Object> getAppletUserInfo(String appid, String encrypteddata, String sessionKey, String iv) {
		return JSON.parseObject(WebchatUtil.decryptEncryptedData(encrypteddata, sessionKey, iv).toJSONString());
	}
	
	/**
	 * 小程序解密绑定phone number
	 */
	@Override
	public Map<String, Object> getAppletPhoneNum(String appid, String encrypteddata, String sessionKey, String iv) {
		return JSON.parseObject(WebchatUtil.decryptEncryptedData(encrypteddata, sessionKey, iv).toJSONString());
	}

}
